#include "smart-device-manager.h"

SmartDeviceManager::SmartDeviceManager(const string &uartDevice)
    : linuxUart(uartDevice)
{
}

void printVectorAsHex(const std::vector<uint8_t> &vec)
{
	for(size_t i = 0; i < vec.size(); ++i)
	{
		printf("%02X ", vec[i]); // %02X 格式化为两位16进制数，不足两位前面补0
	}
	printf("\n");
}

bool SmartDeviceManager::sendPacket(const vector<uint8_t> &packet)
{
	return linuxUart.writeData(packet.data(), packet.size()) < 0 ? false : true;
}

bool SmartDeviceManager::recvPacket(vector<uint8_t> &packet)
{
	// 读取固定9个字节最后2个字节为长度
	// 前9个长度写到packet1里边去
	vector<uint8_t> packet1(SMART_DEVICE_PROTOCOL_PACKET_FIX_LEN);
	int             ret = linuxUart.readFixLenData(packet1.data(), packet1.size());
	if(ret < 0)
	{
		fprintf(stderr, "Fail to readFinxlenData\n");
		return false;
	}

	//读取数据内容
	// 读取长度字段后边的内容
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeProtocolFromPacket(packet1);
	vector<uint8_t>     packet2(protocol.getPacketDataLen() + 2);
	ret = linuxUart.readFixLenData(packet2.data(), packet2.size());
	if(ret < 0)
	{
		fprintf(stderr, "Fail to readFinxlenData\n");
		return false;
	}

	packet.insert(packet.end(), packet1.begin(), packet1.end());
	packet.insert(packet.end(), packet2.begin(), packet2.end());
	return true;
}

bool SmartDeviceManager::openDoorlock(uint8_t deviceType, uint8_t deviceNumber)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeDoorLockProtocol(deviceType, SmatDeviceOpen, deviceNumber);

	vector<uint8_t> ackData;
	//发送数据
	bool ok = this->communication(protocol, ackData);

	cout << "-------------------" << endl;
	printVectorAsHex(ackData);

	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	return ackData[0] == SmartDeviceProtocol::HANDLE_SUCCESS;
}

bool SmartDeviceManager::closeDoorlock(uint8_t deviceType, uint8_t deviceNumber)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeDoorLockProtocol(deviceType, SmatDeviceClose, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	return ackData[0] == SmartDeviceProtocol::HANDLE_SUCCESS;
}

bool SmartDeviceManager::queryDoorlock(uint8_t deviceType, uint8_t deviceNumber, uint8_t &lockStatus)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeDoorLockProtocol(deviceType, SmatDeviceQuery, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	if(ackData[0] != SmartDeviceProtocol::HANDLE_SUCCESS)
	{
		return false;
	}

	lockStatus = ackData[1];
	return true;
}

bool SmartDeviceManager::openElectrical(uint8_t deviceType, uint8_t deviceNumber)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeDoorLockProtocol(deviceType, SmatDeviceOpen, deviceNumber);

	vector<uint8_t> ackData;
	//发送数据
	bool ok = this->communication(protocol, ackData);

	cout << "-------------------" << endl;
	printVectorAsHex(ackData);

	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	return ackData[0] == SmartDeviceProtocol::HANDLE_SUCCESS;
}

bool SmartDeviceManager::closeElectrical(uint8_t deviceType, uint8_t deviceNumber)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeElectricalProtocol(deviceType, SmatDeviceClose, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	return ackData[0] == SmartDeviceProtocol::HANDLE_SUCCESS;
}

bool SmartDeviceManager::queryElectrical(uint8_t deviceType, uint8_t deviceNumber, uint8_t &lockStatus)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeElectricalProtocol(deviceType, SmatDeviceQuery, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	if(ackData[0] != SmartDeviceProtocol::HANDLE_SUCCESS)
	{
		return false;
	}

	lockStatus = ackData[1];
	return true;
}

bool SmartDeviceManager::querySensor(uint8_t deviceType, uint8_t deviceNumber, uint16_t &data)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeSensorcalProtocol(deviceType, SmatDeviceQuery, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	if(ackData[0] != SmartDeviceProtocol::HANDLE_SUCCESS)
	{
		return false;
	}

	data = (ackData[1] << 8 | ackData[2]);
	return true;
}

bool SmartDeviceManager::sniffingDevice(uint8_t deviceType, uint8_t deviceNumber, vector<uint8_t> &info)
{
	SmartDeviceProtocol protocol = SmartDeviceProtocol::makeSniffingProtocol(deviceType, SmatDeviceQuery, deviceNumber);

	vector<uint8_t> ackData;
	bool            ok = this->communication(protocol, ackData);
	if(!ok)
	{
		fprintf(stderr, "Fai to communication");
		return false;
	}
	if(ackData[0] != SmartDeviceProtocol::HANDLE_SUCCESS)
	{
		return false;
	}

	// data = (ackData[1] << 8 | ackData[2]);
	for(int i = 1; i < ackData.size(); i++)
	{
		info.push_back(ackData[i]);
	}

	return true;
}

bool SmartDeviceManager::communication(SmartDeviceProtocol &protocol, vector<uint8_t> &ackData)
{

	vector<uint8_t> sendPaket = vector<uint8_t>(protocol.packetData(),
	                                            protocol.packetData() + protocol.packetLenth());

	//打印发送的字符
	cout << "-------uart发送-------" << endl;
	printVectorAsHex(sendPaket);
	//发送请求
	bool ok = sendPacket(sendPaket);
	if(!ok)
	{
		fprintf(stderr, "Fail to openDoorLock sendPacket\n");
		return false;
	}

	//接收应答
	vector<uint8_t> ackPacket;
	ok = recvPacket(ackPacket);
	if(!ok)
	{
		fprintf(stderr, "Fail to  DoorLock recvPacket\n");
		return false;
	}

	SmartDeviceProtocol ackProtocol = SmartDeviceProtocol::makeProtocolFromPacket(ackPacket);
	if(ackProtocol.isErrorPacket())
	{
		fprintf(stderr, "ACK pageAge is Error\n");
		return false;
	}

	cout << "-------uart接收-------" << endl;
	printVectorAsHex(ackPacket);

	for(int i = 0; i < ackProtocol.getPacketDataLen(); i++)
	{
		ackData.push_back(ackProtocol.getPacketData()[i]);
	}

	// cout << "---------uart接收的长度" << ackProtocol.getPacketDataLen() << "------------" << endl;
	// cout << "-------uart返回的数据-------" << endl;
	// printVectorAsHex(ackData);

	cout << "-------uart发送数据成功-------" << endl;
	return true;
}
